﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Windows.Forms;

namespace ResourceReportBuilder
{
    public partial class MainForm : Form
    {
        private WebResourceCollection _resources;
        private ScriptFileCollection _substituteFiles;
        private TypeReferenceCollection _referenceTypes;

        public MainForm()
        {
            InitializeComponent();
            lblNamespace.Text = "<none>";
            Version ver = Assembly.GetExecutingAssembly().GetName().Version;
            this.Text = string.Format("{0} - Version: {1}.{2}.{3}", this.Text, ver.Major, ver.Minor, ver.Build);
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            (lstFiles.Columns["colMimeType"] as DataGridViewComboBoxColumn).DataSource = MimeTypeCollection.FilledInstance;
            lstFiles.DataError += new DataGridViewDataErrorEventHandler(lstFiles_DataError);
            _substituteFiles = new ScriptFileCollection();
            _resources = new WebResourceCollection();
            lstFiles.DataSource = _resources;
            SetControlsEnabled(false);
        }

        void lstFiles_DataError(object sender, DataGridViewDataErrorEventArgs e)
        {
        }

        private void btnGenerate_Click(object sender, EventArgs e)
        {
            try
            {
                GeneratorForm progressFrm = new GeneratorForm();
                List<string> substFiles = new List<string>();
                foreach (ListViewItem item in substituteFileList.CheckedItems)
                {
                    substFiles.Add(item.Name);
                }
                progressFrm.GenerateReport(lnkProject.Path, lblNamespace.Text, substFiles.ToArray(), _resources);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error during report generation", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                if (Debugger.IsAttached)
                {
                    throw;
                }
            }
        }

        private void lnkProject_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            if (selectProjectDlg.ShowDialog() == DialogResult.OK)
            {
                string content = string.Empty;
                using (StreamReader sr = new StreamReader(selectProjectDlg.FileName))
                {
                    content = sr.ReadToEnd();
                }
                lnkProject.Path = selectProjectDlg.FileName;
                Regex regex = new Regex(@"<RootNamespace>(.*)</RootNamespace>", RegexOptions.IgnoreCase);
                if (regex.IsMatch(content))
                {
                    lblNamespace.Text = regex.Match(content).Groups[1].Value;
                    SetControlsEnabled(true);
                    _referenceTypes = new TypeReferenceCollection(selectProjectDlg.FileName);
                    typeReferenceCollectionBindingSource.DataSource = _referenceTypes;
                }
                else
                {
                    SetControlsEnabled(false);
                }
                selectFolderDlg.SelectedPath = Path.GetDirectoryName(selectProjectDlg.FileName);
                fileBrowser.JumpTo(Path.GetDirectoryName(selectProjectDlg.FileName));
            }
        }

        private void btnAddFiles_Click(object sender, EventArgs e)
        {
            if (selectFilesDlg.ShowDialog() == DialogResult.OK)
            {
                _resources.AddRange(selectFilesDlg.FileNames);
            }
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            _resources.Clear();
        }

        private void SetControlsEnabled(bool enabled)
        {
            btnAddFiles.Enabled = btnClear.Enabled = btnGenerate.Enabled = btnAddFolder.Enabled = btnDelete.Enabled = enabled;
        }

        private void btnAddFolder_Click(object sender, EventArgs e)
        {
            if (selectFolderDlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                _resources.AddRange(Directory.GetFiles(selectFolderDlg.SelectedPath, "*", SearchOption.AllDirectories));
            }
        }

        private void btnDelete_Click(object sender, EventArgs e)
        {
            foreach (DataGridViewRow row in lstFiles.SelectedRows)
            {
                _resources.RemoveAt(row.Index);
            }
        }

        private void fileBrowser_ItemDrag(object sender, ItemDragEventArgs e)
        {
            DoDragDrop(e.Item, DragDropEffects.Copy);
        }

        private void substituteFileList_DragEnter(object sender, DragEventArgs e)
        {
            if (!e.Data.GetDataPresent("System.Windows.Forms.ListViewItem", false))
            {
                e.Effect = DragDropEffects.None;
            }
            else
            {
                e.Effect = DragDropEffects.Copy;
            }
        }

        private void substituteFileList_DragDrop(object sender, DragEventArgs e)
        {
            ListViewItem sourceItem = (ListViewItem)e.Data.GetData("System.Windows.Forms.ListViewItem");
            AddSubstituteFile(sourceItem.Clone() as ListViewItem);
        }

        private void AddSubstituteFile(ListViewItem destItem)
        {
            if (!Path.IsPathRooted(destItem.Text))
            {
                destItem.Text = Path.Combine(fileBrowser.RootPath, destItem.Text);
            }
            destItem.Name = destItem.Text;

            if (substituteFileList.Items[destItem.Name] != null)
            {
                MessageBox.Show("The file has already been added.", "File already added.", MessageBoxButtons.OK, MessageBoxIcon.Information);
                substituteFileList.Items[destItem.Name].Selected = true;
                substituteFileList.Items[destItem.Name].Checked = true;
                return;
            }
            ListViewItem.ListViewSubItem sizeItem = destItem.SubItems.Add(Common.Utils.FormatBytes(new FileInfo(destItem.Text).Length));

            ListViewGroup grp = substituteFileList.Groups[Utils.GetMimeTypeLocal(destItem.Text).Type];
            if (grp == null)
            {
                string groupName = Utils.GetMimeTypeLocal(destItem.Text).Type;
                grp = new ListViewGroup(groupName, groupName);
                substituteFileList.Groups.Add(grp);
            }
            destItem.Group = grp;

            ScriptFile file = new ScriptFile(destItem.Text);
            destItem.Tag = file;
            destItem.Checked = true;
            substituteFileList.Items.Add(destItem);
        }

        private void AddSubstituteFile(string path)
        {
            ListViewItem destItem = new ListViewItem(path);
            AddSubstituteFile(destItem);
        }

        private void fileBrowser_FileDoubleClick(object sender, FileSystemDetailEventArgs e)
        {
            AddSubstituteFile(e.Path);
        }

        private void substMenuSelectAll_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem item in substituteFileList.Items)
            {
                item.Selected = true;
            }
        }

        private void substMenuDelete_Click(object sender, EventArgs e)
        {
            while (substituteFileList.SelectedIndices.Count > 0)
            {
                substituteFileList.Items.RemoveAt(substituteFileList.SelectedIndices[0]);
            }
        }
    }
}
